package com.pai4j.message.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.util.Map;

/**
 * WebSocket健康监控器
 * 
 * 功能：
 * 1. 定期检查Session健康状态
 * 2. 自动清理失效的Session
 * 3. 监控连接数
 * 4. 输出统计信息
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
@Component
public class WebSocketHealthMonitor {

    @Autowired
    private WebSocketSessionManager sessionManager;

    @Autowired(required = false)
    private WebSocketProperties webSocketProperties;

    private volatile boolean enabled = true;

    @PostConstruct
    public void init() {
        if (webSocketProperties != null && webSocketProperties.getHealthCheck() != null) {
            enabled = webSocketProperties.getHealthCheck().isEnabled();
        }
        
        if (enabled) {
            log.info("WebSocket健康监控已启动，检查间隔:{}ms", 
                    webSocketProperties != null && webSocketProperties.getHealthCheck() != null 
                            ? webSocketProperties.getHealthCheck().getInterval() 
                            : 60000L);
        } else {
            log.info("WebSocket健康监控已禁用");
        }
    }

    /**
     * 定期健康检查
     * 每分钟执行一次（可通过配置调整）
     */
    @Scheduled(fixedDelayString = "${pai4j.message.websocket.health-check.interval:60000}")
    public void performHealthCheck() {
        if (!enabled) {
            return;
        }

        try {
            log.debug("开始WebSocket健康检查...");
            
            // 1. 清理失效Session
            int cleaned = 0;
            if (isAutoCleanupEnabled()) {
                cleaned = sessionManager.cleanupInvalidSessions();
            }

            // 2. 获取统计信息
            Map<String, Object> stats = sessionManager.getStatistics();
            
            // 3. 输出统计日志
            log.info("WebSocket健康检查完成 => 总业务场景:{}, 在线用户数:{}, 清理失效会话:{}", 
                    stats.get("totalBizCodes"),
                    stats.get("totalOnlineUsers"),
                    cleaned);

            // 4. 详细统计（DEBUG级别）
            if (log.isDebugEnabled()) {
                @SuppressWarnings("unchecked")
                Map<String, Integer> bizCodeStats = (Map<String, Integer>) stats.get("bizCodeStats");
                if (bizCodeStats != null && !bizCodeStats.isEmpty()) {
                    bizCodeStats.forEach((bizCode, count) -> 
                        log.debug("业务场景:{}, 在线用户数:{}", bizCode, count)
                    );
                }
            }

        } catch (Exception e) {
            log.error("WebSocket健康检查异常：{}", e.getMessage(), e);
        }
    }

    /**
     * 手动触发健康检查
     *
     * @return 统计信息
     */
    public Map<String, Object> manualHealthCheck() {
        log.info("手动触发WebSocket健康检查...");
        
        // 清理失效Session
        int cleaned = sessionManager.cleanupInvalidSessions();
        
        // 获取统计信息
        Map<String, Object> stats = sessionManager.getStatistics();
        stats.put("cleanedSessions", cleaned);
        
        log.info("手动健康检查完成 => {}", stats);
        return stats;
    }

    /**
     * 获取实时统计信息
     *
     * @return 统计信息
     */
    public Map<String, Object> getStatistics() {
        return sessionManager.getStatistics();
    }

    /**
     * 检查用户是否在线
     *
     * @param userId 用户ID
     * @return true-在线，false-离线
     */
    public boolean checkUserOnline(String userId) {
        return sessionManager.isOnline(userId);
    }

    /**
     * 检查用户在特定场景下是否在线
     *
     * @param bizCode 业务代码
     * @param userId 用户ID
     * @return true-在线，false-离线
     */
    public boolean checkUserOnline(String bizCode, String userId) {
        return sessionManager.isOnline(bizCode, userId);
    }

    /**
     * 获取在线用户数
     *
     * @return 在线用户数
     */
    public int getOnlineUserCount() {
        return sessionManager.getTotalOnlineUserCount();
    }

    /**
     * 获取指定业务场景的在线用户数
     *
     * @param bizCode 业务代码
     * @return 在线用户数
     */
    public int getOnlineUserCount(String bizCode) {
        return sessionManager.getOnlineUserCount(bizCode);
    }

    /**
     * 是否启用自动清理
     *
     * @return true-启用，false-禁用
     */
    private boolean isAutoCleanupEnabled() {
        return webSocketProperties != null 
                && webSocketProperties.getHealthCheck() != null
                && webSocketProperties.getHealthCheck().isAutoCleanup();
    }

    /**
     * 启用健康监控
     */
    public void enable() {
        enabled = true;
        log.info("WebSocket健康监控已启用");
    }

    /**
     * 禁用健康监控
     */
    public void disable() {
        enabled = false;
        log.info("WebSocket健康监控已禁用");
    }

    /**
     * 检查健康监控是否启用
     *
     * @return true-启用，false-禁用
     */
    public boolean isEnabled() {
        return enabled;
    }
}

